class_name GamingView
extends BaseView

## TODO 人物技能冷却、武器技能冷却
#region 属性
@export var attenuation_time:float = 0.5
@export var buff_box_item_scene:PackedScene
@onready var health_pb_back: TextureProgressBar = %HealthPBBack
@onready var health_pb_fore: TextureProgressBar = %HealthPBFore
@onready var stamina_pb: ProgressBar = %StaminaPB
@onready var buff_h_flow_container: HFlowContainer = %BuffHFlowContainer
@onready var player_icon: TextureRect = %PlayerIcon
@onready var player_pb: TextureProgressBar = %PlayerPB
@onready var weapon_capacity: Label = %WeaponCapacity
@onready var weapon_icon: TextureRect = %WeaponIcon
@onready var weapon_pb: TextureProgressBar = %WeaponPB
@onready var fps_label: Label = %FPSLabel
var cur_health:int
var cur_max_health:int
var health_tween:Tween
#endregion
#region 字段
#endregion
#region 信号
#endregion

#region 基类方法
func init_view():
	super.init_view()
func on_enter(args:Dictionary = {}):
	super.on_enter()
	var player = GamePlayerSystem.get_player() as PlayerEntity
	var health_component = player.get_component_by_name("HealthComponent") as HealthComponent
	var weapon_component = player.get_component_by_name("WeaponComponent") as WeaponComponent
	var controller_component = player.get_component_by_name("ControllerComponent") as ControllerComponent
	var buff_component = player.get_component_by_name("BuffComponent") as BuffComponent
	if not health_component.on_cur_max_health_changed.is_connected(_on_cur_max_health_changed):
		health_component.on_cur_max_health_changed.connect(_on_cur_max_health_changed)
	if not health_component.on_hit.is_connected(_on_hit):
		health_component.on_hit.connect(_on_hit)
	if not health_component.on_recover.is_connected(_on_recover):
		health_component.on_recover.connect(_on_recover)
	if not health_component.stamina_changed.is_connected(_on_stamina_changed):
		health_component.stamina_changed.connect(_on_stamina_changed)
	if not weapon_component.cur_weapon_changed.is_connected(_on_cur_weapon_changed):
		weapon_component.cur_weapon_changed.connect(_on_cur_weapon_changed)
	health_pb_back.value = 0
	health_pb_fore.value = 0
	cur_max_health = player.get_entity_data().max_health
	_on_cur_max_health_changed(cur_health,cur_max_health)
	_on_recover(health_component.get_cur_health())
	_on_stamina_changed(health_component.cur_stamina,player.get_entity_data().max_stamina)
	var cur_weapon:Weapon = weapon_component.get_cur_weapon()
	_on_cur_weapon_changed(null,cur_weapon)
	var weaponC_capacity = cur_weapon.get_component_by_name("WeaponC_Capacity") as WeaponC_Capacity
	if not weaponC_capacity.on_cur_count_changed.is_connected(_on_weapon_capacity_changed):
		weaponC_capacity.on_cur_count_changed.connect(_on_weapon_capacity_changed)
	_on_weapon_capacity_changed(weaponC_capacity.cur_count)
	GameBuffSystem.start_observering(buff_component,_buff_observer_action)
	player_icon.texture = player.get_entity_data().sprite
	GameManager.translate_game_state(GameEnum.GameState.Gaming)
func on_pause(args:Dictionary = {}):
	super.on_pause()
func on_resume(args:Dictionary = {}):
	super.on_resume()
func on_exit(args:Dictionary = {}):
	var player = GamePlayerSystem.get_player() as PlayerEntity
	var health_component = player.get_component_by_name("HealthComponent") as HealthComponent
	var weapon_component = player.get_component_by_name("WeaponComponent") as WeaponComponent
	var controller_component = player.get_component_by_name("ControllerComponent") as ControllerComponent
	var buff_component = player.get_component_by_name("BuffComponent") as BuffComponent
	health_component.on_cur_max_health_changed.disconnect(_on_cur_max_health_changed)
	health_component.on_hit.disconnect(_on_hit)
	health_component.on_recover.disconnect(_on_recover)
	health_component.stamina_changed.disconnect(_on_stamina_changed)
	var cur_weapon:Weapon = weapon_component.get_cur_weapon()
	var weaponC_capacity = cur_weapon.get_component_by_name("WeaponC_Capacity") as WeaponC_Capacity
	if weaponC_capacity.on_cur_count_changed.is_connected(_on_weapon_capacity_changed):
		weaponC_capacity.on_cur_count_changed.disconnect(_on_weapon_capacity_changed)
	GameBuffSystem.stop_observing(buff_component,_buff_observer_action)
	super.on_exit()
func get_view_state() -> GameEnum.ViewState:
	return super.get_view_state()
#endregion
#region 公共方法
#endregion
#region 私有方法
func _on_hit(cur_health:float):
	if health_tween and health_tween.is_valid():
		health_tween.kill()
	health_tween = create_tween()
	self.cur_health = cur_health
	var fill_value = float(self.cur_health) / float(cur_max_health)
	health_pb_fore.value = fill_value
	health_tween.tween_property(self.health_pb_back,"value",fill_value,attenuation_time).set_ease(Tween.EASE_OUT)
func _on_recover(cur_health:float):
	if health_tween and health_tween.is_valid():
		health_tween.kill()
	health_tween = create_tween()
	self.cur_health = cur_health
	var fill_value = float(self.cur_health) / float(cur_max_health)
	health_pb_back.value = fill_value
	health_tween.tween_property(self.health_pb_fore,"value",fill_value,attenuation_time).set_ease(Tween.EASE_OUT)
func _on_cur_max_health_changed(cur_health,cur_max_health):
	if health_tween and health_tween.is_valid():
		health_tween.kill()
	health_tween = create_tween()
	self.cur_max_health = cur_max_health
	var fill_value = float(self.cur_health) / float(self.cur_max_health)
	if float(self.cur_health) / float(self.cur_max_health + 1) >= float(self.cur_health) / float(cur_max_health + 1):
		health_pb_fore.value = fill_value
		health_tween.tween_property(self.health_pb_back,"value",fill_value,attenuation_time).set_ease(Tween.EASE_OUT)
	else:
		health_pb_back.value = fill_value
		health_tween.tween_property(self.health_pb_fore,"value",fill_value,attenuation_time).set_ease(Tween.EASE_OUT)
func _on_cur_weapon_changed(last_weapon:Weapon,cur_weapon:Weapon):
	var weaponC_capacity:WeaponC_Capacity
	if last_weapon:
		weaponC_capacity = last_weapon.get_component_by_name("WeaponC_Capacity") as WeaponC_Capacity
		if weaponC_capacity.on_cur_count_changed.is_connected(_on_weapon_capacity_changed):
			weaponC_capacity.on_cur_count_changed.disconnect(_on_weapon_capacity_changed)
	weapon_icon.texture = cur_weapon.get_weapon_sprite()
	weaponC_capacity = cur_weapon.get_component_by_name("WeaponC_Capacity") as WeaponC_Capacity
	if not weaponC_capacity.on_cur_count_changed.is_connected(_on_weapon_capacity_changed):
		weaponC_capacity.on_cur_count_changed.connect(_on_weapon_capacity_changed)
func _on_weapon_capacity_changed(cur_count:int):
	var player = GamePlayerSystem.get_player() as PlayerEntity
	var weapon_component = player.get_component_by_name("WeaponComponent") as WeaponComponent
	var total_count = weapon_component.get_cur_weapon().get_entity_data().total_count
	if cur_count < 0:
		weapon_capacity.text = "∞"
	elif total_count < 0:
		weapon_capacity.text = "%d/∞" % cur_count
	else:
		weapon_capacity.text = "%d/%d" %[cur_count,total_count]
func _on_stamina_changed(cur_stamina,cur_max_stamina):
	stamina_pb.value = cur_stamina / cur_max_stamina
func _buff_observer_action(buff:Buff):
	var item:BuffBoxItem = buff_box_item_scene.instantiate() as BuffBoxItem
	buff_h_flow_container.add_child(item)
	item.init_buff_item(buff)
#endregion
#region 生命周期函数
func _process(delta: float) -> void:
	fps_label.text = "FPS:" + str(Engine.get_frames_per_second())
#endregion
